import asyncio
import logging
import re
import string
import imgkit
from aiohttp import ClientSession
from bs4 import BeautifulSoup


from typing import List

from utils.cache_for_time import cache_for_day, cache_for_hour

QUESTOINS_IDS_OFFSET = -1
EGE_BASE_URL = "https://ege.fipi.ru/bank"
EGE_SOLVE_URL = "https://ege.fipi.ru/bank/solve.php"
EGE_QUESTIONS_URL = "https://ege.fipi.ru/bank/questions.php"


class Subject:
    def __init__(self, name: str, id: str):
        self.name = name
        self.id = id


@cache_for_day
async def list_subjects() -> List[Subject]:
    async with ClientSession() as session:
        async with session.get(EGE_BASE_URL, ssl=False) as response:
            html = await response.text()

            soup = BeautifulSoup(html, "html.parser")

            projects = soup.find_all("ul", {"class": "projects active"})

            subjects = []

            for project in projects:
                for li in project.find_all("li"):
                    subject_name = li.text
                    subject_id = li.get("onclick").split('"')[1]

                    subjects.append(Subject(subject_name, subject_id))

            return subjects


def create_question_url(subject_id: str, question_id: int) -> str:
    page = question_id + QUESTOINS_IDS_OFFSET

    return f"{EGE_QUESTIONS_URL}?proj={subject_id}&page={page}&pagesize=1"


async def parse_questions_count(subject_id: str) -> int:
    async with ClientSession() as session:
        params = {
            "proj": subject_id,
        }

        async with session.get(EGE_QUESTIONS_URL, params=params, ssl=False) as response:
            html = await response.text()
            pattern = r"setQCount\((\d+)\)"

            return int(re.search(pattern, html).groups()[0])


async def parse_guid(question_url: str) -> int:
    async with ClientSession() as session:
        async with session.get(question_url, ssl=False) as response:
            html = await response.text()
            pattern = r"changeFavour\(this,'(\w+)'\)"

            return re.search(pattern, html).groups()[0]


async def render_question(url: string) -> bytes:
    return await asyncio.to_thread(imgkit.from_url, url, False)


async def verify_is_answer_correct(guid: str, answer: str):
    RIGHT_ANSWER_CODE = '3'

    php_session_id = await get_php_session_id()

    form_data = {
        'guid': guid,
        'answer': answer,
    }

    cookies = {
        'PHPSESSID': php_session_id,
    }

    async with ClientSession() as session:
        async with session.post(
            EGE_SOLVE_URL,
            data=form_data,
            cookies=cookies,
            ssl=False
        ) as response:
            code = await response.text()

            logging.info(code)
            logging.info(RIGHT_ANSWER_CODE)
            logging.info(code == RIGHT_ANSWER_CODE)

            return code == RIGHT_ANSWER_CODE


@cache_for_hour
async def get_php_session_id():
    async with ClientSession() as session:
        async with session.get(EGE_QUESTIONS_URL, ssl=False) as response:

            return response.cookies.get("PHPSESSID")
